/* // 数组扁平化加去重复
let arr = [1,2,[23,5,[4,6],[88,65]],1,[4,6]]

//扁平化
// flat filter是不会改变原来数组的，会返回一个新的
let tempa1 = arr.flat(Number.MAX_SAFE_INTEGER)
console.log(tempa1)

function flatt(arr){
    return arr.reduce((pre,cur,index,arr)=>{
        if(cur instanceof Array) pre = pre.concat(flatt(cur))
        else pre = pre.concat(cur)
        return pre
    },[])
}
function flatt2(arr){
    let res = []
    arr.map((item,index,arr)=>{
        if(item instanceof Array) res = res.concat(flatt2(item))
        else res.push(item)
    })
    return res
}
let tempa2 = flatt2(arr)
console.log('tempa2:',tempa2)




// 去重
let tempb1 = tempa2.filter((item,index,arr)=>arr.indexOf(item) === index)
let tempb2 = Array.from(new Set(tempa2))
let tempb3 = []
tempa2.forEach((item,index,arr)=>{
    arr.indexOf(item) === index ? tempb3.push(item) : ''
})
console.log(tempb1)
console.log(tempb2)
console.log(tempb3)



// 排序 小-》大
// 冒泡
function float(arr){
    let len = arr.length
    for(let i = 0; i < len - 1; i++){
        for(let j = 0; j < len - i - 1; j++){
            if(arr[j] > arr[j + 1]){
                let temp = arr[j]
                arr[j] = arr[j + 1]
                arr[j + 1] = temp
            }
        }
    }
}
// 快速排序
function quick(arr,start,stop){
    if(start >= stop) return
    // debugger;
    let left = start
    let right = stop
    while(left < right){
        while(arr[left]<arr[right]){
            right--
        }
        if(arr[left] > arr[right]){
            let temp = arr[right]
            arr[right] = arr[left]
            arr[left] = temp
        }
        while(arr[right] > arr[left]){
            left++
        }
        if(arr[left] > arr[right]){
            let temp = arr[right]
            arr[right] = arr[left]
            arr[left] = temp
        }
    }
    quick(arr,start,left - 1)
    quick(arr,left + 1,stop)
}
let floatarr = [1,3,5,9,8,6,7,2,10]
let quickarr = [1,3,5,9,8,6,7,2,10,0]
float(floatarr)
console.log(floatarr)

quick(quickarr,0,quickarr.length - 1)
console.log(quickarr) */

// jsonp

/* function jsonp(url,cal,data){
    let script = document.createElement('script')
    url = url+'?'
    for(let key in data){
        url = url + key + '=' + data[key] + '&'
    }
    url = url + 'callback' + cal
    // url = url.subString(0,url.length - 1)
    script.src = url
    let dom = document.querySelector('body')
    dom.appendChild(script)
    dom.removeChild(script)
    // console.log(url)
}
let url = 'http://baidu.com'
let data = {id:1,name:'feifei'}
cal = function(){
    console.log(12)
}
jsonp(url,cal,data) */
/* // 手写instantof
function MyInstantof(a,A){
    // 判断a的原型链上是否有A
    let b = a
    let res = false
    while(b){
        if(b.__proto__ === A.prototype){
            res = true
            break
        }
        b = b.__proto__
    }
    return res
}
let s = new String('123')
let d = MyInstantof(s,Number)
console.log(d) */


/* function Jon(arr1,arr2){
    let len1 = arr1.length
    let len2 = arr2.length
    let i = 0
    let j = 0
    let res = []
    for(;i < len1 && j < len2;){
        if(arr1[i] > arr2[j]) res.push(arr2[j++])
        else res.push(arr1[i++])
    }
    res = res.concat(arr1.slice(i,len1))
    res = res.concat(arr2.slice(j,len2))
    console.log(res)
}
let arr1 = [1,4,7,10,11]
let arr2 = [2,3,5,8,9,12,13,15]
Jon(arr1,arr2) */

//判断输出
/* console.log(0);

setTimeout(() => {
    console.log(1);
});
 */
/* var data = {};
for (var i = 0; i < 10; i++) {
    data[i] = function(){console.log(i)}
}
console.log(data[8]()); */
/* var p = new Promise((res, rej) => {
    console.log(2);
    res(3);
});

p.then(data => {
    console.log(data);
}); */


/* function _new(){
    // 创建一个空对象
    let obj = {}
    let con = [].unshift.call(arguments)
    obj.__proto__ = con.prototype
    con.call(obj,...arguments)
    return obj
} */


// 手写reduce

/* let arr = [1,2,3]

Array.prototype.reduce = function(fn,init){
    let that = this
    let len = that.length
    let res = init
    for(let i = 0; i < len; i++){
        res = fn(res,that[i],i,that)
        console.log('run')
    }
    return res
}

let temp = arr.reduce((pre,cur,index,arr)=>{
    pre.push(cur+1)
    return pre
},[])
console.log(temp) */



/* function lazy(){
    let imgs = document.querySelectorAll('img')
    let len = imgs.length
    let H = document.documentElement.clientHeight
    let S = document.documentElement.scrollTop
    for(let i = 0; i < len; i++){
        if(getOffset(imgs[i]) < H + S){
            img[i].src = img[i].getAttribute('data-src')
        }
    }
} */


1. Dom tree 形成过程

html AST抽象语法树

dom解析过程

<style></style>

<script>
</script>
defer async 区别
js css dom加载顺序


<img src=""> 请求过程会阻塞js吗
阻塞

http 缓存 网络资源缓存
协商缓存
cache-control
no-store
no-cache

cookie 作用
硬盘
document.cookie

tcp 连接 http keep-alive

http2

重排 重绘：

position: relative;
top: 20px;
display: none;
opcatiy: 0;
硬件加速



1. this 指向
箭头函数

作用域

in
out
peek
实现栈

app.vue

<template>
</tempate>
<script>
</script>

Promise.all
const repeatFunc = repeat(console.log, 4, 3000)
repeatFunc("helloworld")
// 会输出四次 helloworld，每次间隔 3s

// setInterval()
function repeat(cb, count, time) {
  // 
    let ti =  count
    let pick 
    return function(thing){
        let that = this
        pick= setIverll(()=>{
            if(ti <=0) clearInterval(pick)
            ti --
            cb.call(that,...thing)
        
    },time)
    }
}
